home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / sound / rukq10.zip / X01_71.BAS < prev    next >
BASIC Source File  |  1993-02-15  |  11KB  |  326 lines

  1. DECLARE FUNCTION InitDevice% (device%, SIP AS ANY, IP AS ANY)
  2. DECLARE FUNCTION PickDevice% (SIP AS ANY, XMSflag%)
  3.  
  4. REM $INCLUDE: 'RUCKDAC.BI7'
  5.  
  6. '--------------------------------------
  7. 'SEE X01.BAS FOR QUICKBASIC 4.5 EXAMPLE
  8. '--------------------------------------
  9.  
  10. 'X01_71.BAS - load and play digital data file into DOS memory
  11. '
  12. '        - The SB is always played in DMA mode in this example, this means
  13. '        - that stereo or high-sample rate files will not play correctly;
  14. '        - they will play correctly on an SB PRO or on the other devices.
  15. '        - To play stereo or high-sample rate files on the SB, PBP.Mode
  16. '        - must be set to either 0 or 1 (i.e., non-SB/DMA mode).
  17. '
  18. '31-Jan-93 -chh
  19. 'C>bc X01_71 /o;
  20. 'C>link X01_71,X01_71.EXE,nul,RUCKDAC.LIB;
  21. ver$ = "[930131]"
  22.  
  23. DEFINT A-Z
  24.  
  25. 'The packs could be made global but passing them as paramters works
  26.  
  27. DIM SIP AS SysInfoPackTYPE
  28. DIM IP AS InitPackTYPE
  29. DIM LP AS LoadPackTYPE
  30. DIM SP AS SetPackTYPE
  31. DIM PBP AS PlaybackPackTYPE
  32. DIM GDP AS GetDataPackTYPE
  33. DIM DP AS DeallocPackTYPE
  34. DIM XP AS XitPackTYPE
  35.  
  36. CLS
  37. PRINT "X01_71.BAS - RUCKUS-DAC play of VOC or WAVE file example."; ver$
  38.  
  39. InIDE = -1     'since the IDE needs more than 2K available, use this to
  40.                'flag if operating in QB's ennvironment
  41.  
  42. 'RUCKDAC uses memory from the operating system pool
  43. 'since BASIC starts up claiming all memory, instruct it to return excess
  44. 'memory back to OS pool
  45.  
  46. nix& = SETMEM(700000)           'return to QB environment any previous release
  47. nix& = SETMEM(0)                'see how much is available
  48. nix& = nix& - 2100              'release all but 2K to operating system
  49.  
  50. IF InIDE THEN
  51.    nix& = nix& - 66000          'leave 64K more for IDE
  52.    XP.Func = ExitDac            'and shut down any loose ends
  53.    nix = RUCKDAC(XP)
  54. END IF
  55.  
  56. nix& = SETMEM(-nix&)            'this call does the actual release
  57.  
  58. 'pick device to use
  59.  
  60. devID = PickDevice(SIP, XMSflag)'id system and get device to use
  61. IF devID < 0 THEN PRINT "Ended.": END
  62.  
  63. CLS
  64. LOCATE 5
  65.  
  66. 'initialize the selected device and register ExitDac via AtExitDac
  67.  
  68. stat = InitDevice(devID, SIP, IP)
  69. IF stat = 0 THEN
  70.    
  71.    'The following load and play example source is coded inline here
  72.    'to simplify readability -- but it's so easy to add things I just
  73.    'kept adding stuff, so take it slow if you don't follow at first
  74.  
  75.    'load file and setup playback parameters
  76.  
  77.    INPUT "VOC/WAVE filename: ", filename$
  78.    filename$ = filename$ + CHR$(0)        'DOS requires ASCIIZ name
  79.    LP.Func = LoadDac
  80.  
  81.    'LP.FilenamePtrOff = SADD(filename$)    'QB format
  82.    'LP.FilenamePtrSeg = VARSEG(filename$)
  83.    LP.FilenamePtrOff = SADD(filename$)    'BASIC7 format
  84.    LP.FilenamePtrSeg = SSEG(filename$)
  85.  
  86.    LP.StartPos = 0&     'start load at byte 0 of filename$
  87.    LP.LoadSize = 0&     'load entire file
  88.    LP.XMMflag = XMSflag 'load into DOS or XMS memory (selected in PickDevice)
  89.    stat = RUCKDAC(LP)
  90.  
  91.    IF stat = 0 THEN
  92.    
  93.       'immediately after load, but before play if non-DMA, we can peek
  94.       'into the DAC data to get the file's recorded sample rate, in case
  95.       'of SR > 32767, we just add 65536 to get unsigned value
  96.  
  97.       DEF SEG = IP.InfoPtrSeg
  98.       bp = IP.InfoPtrOff
  99.       fileSR& = 256 * PEEK(bp + 25) + PEEK(bp + 24)
  100.       IF fileSR& < 0 THEN fileSR& = fileSR& + 65536
  101.       PRINT " Sample rate:"; fileSR&; "Hz (at load time)"
  102.       PRINT " File format: ";
  103.       IsStereo = PEEK(bp + 26)
  104.       FormatIs = PEEK(bp + 20)
  105.       IF IsStereo THEN PRINT "Stereo";  ELSE PRINT "Mono";
  106.       IF FormatIs = 1 THEN PRINT " voc" ELSE PRINT " wave"
  107.       DEF SEG
  108.  
  109.       'data is loaded, if device is a Sound Blaster, use DMA at
  110.       'file sample rate else set rate to either file sample rate, or
  111.       'if > 11025 (most ATs can handle 11kHz in non-DMA mode), set to 8000
  112.  
  113.       PBP.Func = PlayDac
  114.       IF devID >= 4 THEN
  115.          PBP.Mode = 2
  116.       ELSE
  117.          SP.Func = SetIntRateDac
  118.  
  119.          'to play hal.voc using PCSPKR1 (the hi-rez mode) set
  120.          'SP.IntRate=8463. This results in an upsample rate of 17045Hz
  121.  
  122.          IF fileSR& < 11025 THEN     'if the recorded sample rate is <11025
  123.             SP.IntRate = fileSR&     'according to the VOC or WAVE file hdr
  124.          ELSE                        'then just go ahead and use that, else
  125.             SP.IntRate = 8000        'down sample to 8000 (or closest fit)
  126.          END IF
  127.  
  128.          stat = RUCKDAC(SP)
  129.  
  130.          IF stat THEN
  131.             PRINT "Unexpected error at SetIntRateDac, stat:"; stat
  132.             END
  133.          END IF
  134.  
  135.          PBP.Mode = 1
  136.       END IF
  137.  
  138.       IF LP.XMMflag = 0 THEN
  139.          PBP.XMMhandle = 0
  140.          PBP.LoadPtrOff = LP.LoadPtrOff
  141.          PBP.LoadPtrSeg = LP.LoadPtrSeg
  142.       ELSE
  143.          PBP.XMMhandle = LP.XMMhandle
  144.          PBP.LoadPtrOff = 0
  145.          PBP.LoadPtrSeg = 0
  146.          IF PBP.Mode < 2 THEN PRINT "Loading into XMS requires DMA mode.": END
  147.       END IF
  148.       stat = RUCKDAC(PBP)
  149.  
  150.       IF stat = 0 THEN
  151.  
  152.          'Playing in the background, wait until done or key pressed.
  153.          'To check if data done playing, read directly into DAC data segment
  154.          'and check to word at offset +10. Checking just the byte will do.
  155.  
  156.          DEF SEG = IP.InfoPtrSeg
  157.          bp = IP.InfoPtrOff
  158.  
  159.          actualSR& = 256& * PEEK(bp + 25) + PEEK(bp + 24)
  160.          IF actualSR& < 0 THEN actualSR& = actualSR& + 65536
  161.  
  162.          usedK = 256 * PEEK(bp + 23) + PEEK(bp + 22)
  163.          DOSleftK = 256 * PEEK(bp + 17) + PEEK(bp + 16)
  164.          XMSleftK = 256 * PEEK(bp + 19) + PEEK(bp + 18)
  165.  
  166.          PRINT "   Device ID:"; devID
  167.          PRINT "   Play rate:"; actualSR&; "Hz"
  168.  
  169.          IF LP.XMMflag = 0 THEN
  170.             PRINT " Memory type: DOS"
  171.             PRINT "K bytes left:"; DOSleftK
  172.             PRINT "K bytes used:"; usedK
  173.             PRINT "Load address: "; RIGHT$("000" + HEX$(LP.LoadPtrSeg), 4) + ":" + RIGHT$("000" + HEX$(LP.LoadPtrOff), 4)
  174.          ELSE
  175.             PRINT " Memory type: XMS"
  176.             PRINT "K bytes left:"; XMSleftK
  177.             PRINT "K bytes used:"; usedK
  178.             PRINT "  XMS handle:"; LP.XMMhandle
  179.          END IF
  180.  
  181.          PRINT "Current byte: ";
  182.          CurrRow = CSRLIN
  183.          CurrCol = POS(0)
  184.  
  185.          byte& = 0&
  186.          DO
  187.             DacIsDone = PEEK(bp + 10)
  188.  
  189.             'do something to demonstate playback is a background operation
  190.             'here we just get the current byte position and print if not 0
  191.  
  192.             LOCATE CurrRow, CurrCol
  193.             GDP.Func = GetBytePosDac
  194.             nix = RUCKDAC(GDP)
  195.  
  196.             IF GDP.BytePos <> 0 THEN byte& = GDP.BytePos
  197.             PRINT RIGHT$("000000" + HEX$(byte&), 7)
  198.  
  199.          LOOP UNTIL (DacIsDone <> 0) OR LEN(INKEY$)
  200.          DEF SEG
  201.  
  202.          'end play
  203.  
  204.          XP.Func = EndDac
  205.          stat = RUCKDAC(XP)
  206.  
  207.          'release memory used by LoadDac (ExitDac would do that, too)
  208.  
  209.          DP.Func = DeallocDac
  210.          IF LP.XMMflag = 0 THEN
  211.             DP.HandSeg = LP.LoadPtrSeg
  212.             DP.TypeFlag = 0
  213.          ELSE
  214.             DP.HandSeg = LP.XMMhandle
  215.             DP.TypeFlag = 1
  216.          END IF
  217.          stat = RUCKDAC(DP)
  218.  
  219.       ELSE
  220.          PRINT "Play of "; filename$; "failed, stat:"; stat
  221.       END IF
  222.  
  223.    ELSE
  224.       PRINT "Load of "; filename$; "failed, stat:"; stat
  225.    END IF
  226.  
  227. ELSE
  228.    PRINT "InitDevice failed, stat:"; stat
  229. END IF
  230.  
  231. 'shut down RUCKDAC and end program
  232.  
  233. XP.Func = ExitDac
  234. nix = RUCKDAC(XP)
  235. PRINT "  Done, stat:"; stat
  236. nix& = SETMEM(700000)   'return to QB environment any previous release
  237. END
  238.  
  239. FUNCTION InitDevice (device, SIP AS SysInfoPackTYPE, IP AS InitPackTYPE)
  240.  
  241. 'Initialize RUCKDAC and device and register ExitDac with _atexit
  242. 'The IP.port for devices 0 and 3 are set to 0 for low-rez mode, or their
  243. 'repective actual ports for hi-rez mode (&H42 and &H388)
  244.  
  245. DIM XP AS XitPackTYPE   'local use for AtExitDac
  246.  
  247. IP.Func = InitDac
  248. IP.DeviceID = device
  249. SELECT CASE device
  250. CASE 0: IP.IOport = 0:          IP.IRQline = SIP.D0IRQ: IP.DMAch = SIP.D0DMA
  251. CASE 1: IP.IOport = SIP.D1port: IP.IRQlin